﻿using DeHeng_Mes.Model.Table;
using GXWA_DATA.Config;
using GXWA_DATA.Dao;
using GXWA_DATA.Model.ApiModel;
using GXWA_DATA.Model.DetailModel;
using GXWA_DATA.Model.Singleton;
using GXWA_DATA.Model.Table;
using GXWA_DATA.Utils;
using System.Net;
using System.Text;
using System.Text.Json;
using static System.Windows.Forms.Design.AxImporter;

namespace GXWA_DATA.ThreadTask
{
    public class DetailsTask
    {
        #region 成员变量
        DataDao dataDao = new DataDao();
        #endregion

        public async Task GetDetailData()
        {
            Tools.ProduceLogText("正在开启监听服务...");
            try
            {
                using (HttpListener listener = new HttpListener())
                {
                    // 添加监听地址
                    listener.Prefixes.Add("http://192.168.10.2:7512/");

                    // 启动监听
                    listener.Start();
                    Tools.ProduceLogText("监听服务开启成功!");

                    while (true)
                    {
                        // 异步等待客户端请求
                        HttpListenerContext context = await listener.GetContextAsync();

                        string absolutePath = context.Request.Url.AbsolutePath;

                        if (string.IsNullOrEmpty(absolutePath))
                            Tools.ProduceLogTextError($"错误的URL，[{context.Request.Url}]");

                        // 判断请求对应的方法
                        switch (absolutePath)
                        {
                            case "/OrderDispatch":
                                _ = OrderDicpatch(context);
                                break;
                            case "/OrderReport":
                                _ = OrderReport(context);
                                break;
                            case "/CheckReport":
                                _ = CheckReport(context);
                                break;
                            default:
                                Tools.ProduceLogTextError($"未知的Url，[{context.Request.Url}]");
                                break;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Tools.ProduceLogTextError("监听服务开启失败，原因是：" + ex.Message);
            }
        }

        private async Task CheckReport(HttpListenerContext context)
        {
            // 初始化响应内容和状态码
            string responseString = string.Empty; // 存储最终的响应内容
            int statusCode = (int)HttpStatusCode.OK; // 默认状态码为200 (OK)

            try
            {
                // 确保请求是 POST 方法
                if (context.Request.HttpMethod != "POST")
                {
                    // 如果请求不是POST方法，则返回未知请求的响应信息
                    responseString = BuildResponse(false, "未知请求");
                    Tools.ProduceLogText($"接收到一个未知的请求方式，请求方式为：{context.Request.HttpMethod}");
                }
                else
                {
                    // 使用 StreamReader 读取请求数据流中的内容
                    using (var reader = new StreamReader(context.Request.InputStream, context.Request.ContentEncoding))
                    {
                        string jsonContent = reader.ReadToEnd();

                        string cleanedString = jsonContent.StartsWith("json=")
                                             ? jsonContent.Substring("json=".Length)
                                             : jsonContent;

                        OrderApiCloseModel orderData = JsonSerializer.Deserialize<OrderApiCloseModel>(cleanedString);

                        responseString = BuildResponse(true, "成功！");
                    }
                }
            }
            catch (JsonException ex)
            {
                // 捕获 JSON 格式解析异常，表示请求数据格式错误，设置状态码为400 (Bad Request)
                responseString = BuildResponse(false, "请求数据格式错误");
                statusCode = (int)HttpStatusCode.BadRequest;
                Tools.ProduceLogTextError("失败，原因是：" + ex.Message);
            }
            catch (Exception ex)
            {
                // 捕获所有其他异常，表示服务器内部错误，设置状态码为500 (Internal Server Error)
                responseString = BuildResponse(false, "服务器内部错误");
                statusCode = (int)HttpStatusCode.InternalServerError;
                Tools.ProduceLogTextError("失败，服务器内部错误：" + ex.Message);
            }
            finally
            {
                // 发送响应数据
                await SendResponseAsync(context, responseString, statusCode);

                Tools.ProduceLogText(responseString);
            }
        }

        /// <summary>
        /// 工单结束
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        private async Task OrderReport(HttpListenerContext context)
        {
            // 初始化响应内容和状态码
            string responseString = string.Empty; // 存储最终的响应内容
            int statusCode = (int)HttpStatusCode.OK; // 默认状态码为200 (OK)

            try
            {
                // 确保请求是 POST 方法
                if (context.Request.HttpMethod != "POST")
                {
                    // 如果请求不是POST方法，则返回未知请求的响应信息
                    responseString = BuildResponse(false, "未知请求");
                    Tools.ProduceLogText($"接收到一个未知的请求方式，请求方式为：{context.Request.HttpMethod}");
                }
                else
                {
                    // 使用 StreamReader 读取请求数据流中的内容
                    using (var reader = new StreamReader(context.Request.InputStream, context.Request.ContentEncoding))
                    {
                        string jsonContent = reader.ReadToEnd();

                        string cleanedString = jsonContent.StartsWith("json=")
                                             ? jsonContent.Substring("json=".Length)
                                             : jsonContent;

                        OrderApiCloseModel orderData = JsonSerializer.Deserialize<OrderApiCloseModel>(cleanedString);

                        dataDao.OrderClose(orderData);

                        // 清除工单缓存
                        OrderSingleton.Delete(orderData);

                        // 清除产量缓存
                        ProductionSingleton.ClearByOrder(orderData.OrderCode);

                        responseString = BuildResponse(true, "结束成功！");
                    }
                }
            }
            catch (JsonException ex)
            {
                // 捕获 JSON 格式解析异常，表示请求数据格式错误，设置状态码为400 (Bad Request)
                responseString = BuildResponse(false, "请求数据格式错误");
                statusCode = (int)HttpStatusCode.BadRequest;
                Tools.ProduceLogTextError("失败，原因是：" + ex.Message);
            }
            catch (Exception ex)
            {
                // 捕获所有其他异常，表示服务器内部错误，设置状态码为500 (Internal Server Error)
                responseString = BuildResponse(false, "服务器内部错误");
                statusCode = (int)HttpStatusCode.InternalServerError;
                Tools.ProduceLogTextError("失败，服务器内部错误：" + ex.Message);
            }
            finally
            {
                // 发送响应数据
                await SendResponseAsync(context, responseString, statusCode);

                Tools.ProduceLogText(responseString);
            }
        }

        /// <summary>
        /// 接收工单
        /// </summary>
        private async Task OrderDicpatch(HttpListenerContext context)
        {
            // 初始化响应内容和状态码
            string responseString = string.Empty; // 存储最终的响应内容
            int statusCode = (int)HttpStatusCode.OK; // 默认状态码为200 (OK)

            try
            {
                // 确保请求是 POST 方法
                if (context.Request.HttpMethod != "POST")
                {
                    // 如果请求不是POST方法，则返回未知请求的响应信息
                    responseString = BuildResponse(false, "未知请求");
                    Tools.ProduceLogText($"接收到一个未知的请求方式，请求方式为：{context.Request.HttpMethod}");
                }
                else
                {
                    // 使用 StreamReader 读取请求数据流中的内容
                    using (var reader = new StreamReader(context.Request.InputStream, context.Request.ContentEncoding))
                    {
                        string jsonContent = reader.ReadToEnd();

                        string cleanedString = jsonContent.StartsWith("json=")
                                             ? jsonContent.Substring("json=".Length)
                                             : jsonContent;

                        OrderApiModel orderData = JsonSerializer.Deserialize<OrderApiModel>(cleanedString);

                        // 工单号相同防错
                        if(dataDao.OrderIsSaveByOrderId(orderData.OrderCode))
                            responseString = BuildResponse(false, "存在相同工单号！");

                        // 物料编码唯一防错
                        List<OrderStatus> orderStatuses = dataDao.QueryOrder().Where(x => x.MaterialId == orderData.MaterialCode).ToList();

                        if(orderStatuses.Count > 0)
                            responseString = BuildResponse(false, "存在相同物料！");

                        OrderStatus orderStatus = new OrderStatus()
                        {
                            OrderId = orderData.OrderCode,
                            ProductionPlan = orderData.PlanNum,
                            MaterialId = orderData.MaterialCode,
                            MaterialName = orderData.MaterialName,
                            OrderIssuedTime = DateTime.Now,
                            ShiftName = orderData.ShiftName,
                            LineName = orderData.LineName,
                            Status = "1"
                        };

                        // 存储工单
                        dataDao.SaveOrder(orderStatus);

                        // 添加工单至缓存
                        OrderSingleton.Add(orderStatus);

                        // 初始化工单产量
                        Dictionary<string, int> dictionary = MappingTable.GetStation();

                        dictionary = dictionary.Where(x => x.Key.Contains("Op")).ToDictionary();

                        List<TraceProduction> productions = new List<TraceProduction>();

                        foreach (var item in dictionary)
                        {
                            TraceProduction traceProduction = new TraceProduction()
                            {
                                OrderId = orderData.OrderCode,
                                Station = item.Key,
                                ProductionNg = 0,
                                ProductionNum = 0,
                            };

                            productions.Add(traceProduction);

                            // 缓存产量
                            ProductionSingleton.Add(traceProduction);
                        }

                        // 数据库存储产量数据
                        dataDao.SaveProductionData(productions);

                        responseString = BuildResponse(true, "下发成功！");
                    }
                }
            }
            catch (JsonException ex)
            {
                // 捕获 JSON 格式解析异常，表示请求数据格式错误，设置状态码为400 (Bad Request)
                responseString = BuildResponse(false, "请求数据格式错误");
                statusCode = (int)HttpStatusCode.BadRequest;
                Tools.ProduceLogTextError("失败，原因是：" + ex.Message);
            }
            catch (Exception ex)
            {
                // 捕获所有其他异常，表示服务器内部错误，设置状态码为500 (Internal Server Error)
                responseString = BuildResponse(false, "服务器内部错误");
                statusCode = (int)HttpStatusCode.InternalServerError;
                Tools.ProduceLogTextError("失败，服务器内部错误：" + ex.Message);
            }
            finally
            {
                // 发送响应数据
                await SendResponseAsync(context, responseString, statusCode);
            }
        }

        private string BuildResponse(bool result, string msg) =>
            JsonSerializer.Serialize(new { result, msg });

        /// <summary>
        /// 发送响应
        /// </summary>
        /// <param name="context"></param>
        /// <param name="responseString"></param>
        /// <param name="statusCode"></param>
        /// <returns></returns>
        private async Task SendResponseAsync(HttpListenerContext context, string responseString, int statusCode)
        {
            try
            {
                // 将响应字符串转换为 UTF-8 字节数组，以便写入到响应流中
                byte[] buffer = Encoding.UTF8.GetBytes(responseString);

                // 设置响应内容的长度（字节数），ContentLength64 告诉客户端响应体的大小，便于接收完整的响应数据
                context.Response.ContentLength64 = buffer.Length;

                // 设置响应的内容类型为 JSON，告知客户端响应的数据格式
                context.Response.ContentType = "application/json";

                // 设置响应的 HTTP 状态码，指示请求的处理结果状态
                context.Response.StatusCode = statusCode;

                // 异步写入响应内容到输出流，将字节数组内容从起始位置写到响应流中
                await context.Response.OutputStream.WriteAsync(buffer, 0, buffer.Length);

                // 关闭响应输出流，表示响应已经完成，释放资源
                context.Response.OutputStream.Close();
            }
            catch (Exception ex)
            {
                Tools.ProduceLogTextError($"发送响应失败，原因是：{ex.Message}");
            }
        }
    }
}
